\documentclass[10pt,a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[brazil]{babel}
\usepackage[utf8]{inputenc}

\newcommand{\red}[1]{\textcolor{red}{#1}}

\usepackage{ae,aecompl}
\usepackage{pslatex}
\usepackage{epsfig}
\usepackage{geometry}
\usepackage{url}
\usepackage{textcomp}
\usepackage{ae}
\usepackage{subfig}
\usepackage{indentfirst}
\usepackage{textcomp}
\usepackage{color}
\usepackage{setspace}
\usepackage{verbatim}
\usepackage{multicol}

\usepackage{listings}
\lstset{language=C}
\usepackage{listings}
\lstset{
  basicstyle=\footnotesize\ttfamily, % Standardschrift
  numbers=left,               % Ort der Zeilennummern
  numberstyle=\tiny,          % Stil der Zeilennummern
  % stepnumber=2,               % Abstand zwischen den Zeilennummern
  numbersep=5pt,              % Abstand der Nummern zum Text
  tabsize=2,                  % Groesse von Tabs
  extendedchars=true,         %
  breaklines=true,            % Zeilen werden Umgebrochen
  classoffset=0,
  keywordstyle=\color{blue},
  classoffset=1,
  morekeywords={factor},keywordstyle=\color{red},
  classoffset=0,
  % frame=b,         
  % keywordstyle=[1]\textbf,    % Stil der Keywords
  % keywordstyle=[2]\textbf,    %
  % keywordstyle=[3]\textbf,    %
  % keywordstyle=[4]\textbf,   \sqrt{\sqrt{}} %
  stringstyle=\color{green}\ttfamily, % Farbe der String
  showspaces=false,           % Leerzeichen anzeigen ?
  showtabs=false,             % Tabs anzeigen ?
  xleftmargin=17pt,
  framexleftmargin=17pt,
  framexrightmargin=5pt,
  framexbottommargin=4pt,
  % backgroundcolor=\color{lightgray},
  showstringspaces=false      % Leerzeichen in Strings anzeigen ?        
}
\lstloadlanguages{C
}

% Definindo o espaçamento entre linhas para 1.5
% Relatório parcial deve ter espaçamento simples
\linespread{1.5}

\geometry{ 
  a4paper,	% Formato do papel
  tmargin=30mm,	% Margem superior
  bmargin=30mm,	% Margem inferior
  lmargin=20mm,	% Margem esquerda
  rmargin=20mm,	% Margem direita
  footskip=20mm	% Espaço entre o rodapé e o fim do texto
}
\include{abaco} 
\renewcommand{\thetable}{\Roman{table}}
\newcommand{\x} {$\bullet$}


\begin{document}

% CAPA
\begin{titlepage}
  \thispagestyle{empty}
  \begin{center} {\large \textbf{UNIVERSIDADE~ESTADUAL~DE~CAMPINAS}} \end{center}
  \begin{center} {\large INSTITUTO~DE~COMPUTAÇÃO}                    \end{center}
  \vspace{0.1cm}
  \begin{center}
    \begin{minipage}[tl]{31mm}
      \ABACO{1}{9}{6}{9}{1}
    \end{minipage}
  \end{center}
  \vspace{0.3cm}
  \begin{center} 
    {\large \textsc{Servidor de Agenda baseado em socket UDP
      }} 
    \\\vspace{0.5cm}
    {\textsl{Relatório do segundo laboratório de MC823}}
    \\\vspace{1cm}
    \begin{tabular}{ll}
      \textbf{Aluno}:        Marcelo~Keith~Matsumoto   &  \textbf{RA}:       085937 \\
      \textbf{Aluno}:        Tiago~Chedraoui~Silva    &   \textbf{RA}:       082941 \\
      
    \end{tabular}
  \end{center}
  \vspace{0.5cm}

  \begin{abstract}
O protocolo UDP (User Datagram Protocol) é um protocolo do nível da camada de
transporte. Ele é apropriado para aplicações
tempo real, como telefonia e transferência de áudio e
vídeo sobre a Internet. Dentre usas principais características temos:
Não orientado à conexão, sem transferência de dados garantida, não
guarda o estado de conexão.

Utilizando esse protocolo desenvolveu-se uma aplicação distribuída
que simulava uma agenda para o mês de abril, com diversas funções (inserção de dados na agenda, recuperação de
dados, remoção de dados), através da qual foi
possível observar o
funcionamento de uma comunicação via UDP entre um
cliente e um servidor em máquinas diferentes. Para isso, a interação
entre ambos ocorria  através do envio de dados  do
cliente para o servidor, assim como na outra direção, utilizando
sockets criados.

Por fim, foi realizado uma análise dos tempo de de comunicação,
processamento e total do programa, no qual concluiu-se que os
tempos de  processamento são significativamente maiores que os tempos de conexão.
  \end{abstract}

\end{titlepage} 
  % Sumário
  \tableofcontents

\newpage


% -----------------------------------------------------------------------------%
\section{Motivação}
% -----------------------------------------------------------------------------%
Atualmente, com o crescente aumento de dispositivos móveis e computadores conectados à rede, o conhecimento da comunicação tem se tornado cada vez mais importante para quem trabalha na área de tecnologia. Um dos maiores exemplos da importância da comunicação entre computadores é em um sistema distribuído.

Um sistema distribuído é uma "coleção de computadores independentes que se apresenta ao usuário como um sistema único e consistente"\cite{AST}. Para que isso seja possível, diversos computadores estão interligados por uma rede de computadores, através da qual compartilham entre si objetos (como arquivos, informações, processamento, etc) e são responsáveis por manter uma consistência nesses objetos. 
Portanto, hoje, um servidor não é apenas um computador, mas sim vários
computadores em locais diferentes que aparentam ser, para um usuário,
um único sistema.

Com o objetivo de otimizar a comunicação entre computadores que venham
a requerir os dados na rede, esse trabalho visa estudar o tempo de
comunicação entre máquinas que utilizam sockets para tal finalidade.

\subsection{Teoria}
O UDP (User Datagram Protocol) é um protocolo do nível da camada de
transporte~\cite{Kurose05}. Dentre usas principais características temos:

\begin{description}
\item[Não orientado à conexão]  Não há abertura de conexão para o envio de dados. Não introduzindo, portanto, atrasos para esta tarefa.
\item[Sem transferência de dados garantida] Não há garantia de entrega
  de dados livre de erros entre o processo emissor e receptor; 
\item[Não estado de conexão] Não mantém estado da conexão, que implicaria em buffers de envio e recepção,números de seqüência e reconhecimento.
\item[informações de controle] Tem informações de controle pequeno no cabeçalho.
\item[ Sem controle de fluxo] Taxa de envio sem regulação ou controle de fluxo.

\end{description}

Cada um dos segmentos da camada transporte tem em seu cabeçalho campos
denominado número de portas que indicam a qual processo o mesmo deve
ser entregue, existindo um número de porta do emissor e o número de porta do
receptor. 

Possuindo as duas portas, pode-se realizar uma conexão entre elas
conhecida por socket. Com o socket é possível diferenciar os canais
utilizados por cada processo de aplicação.

O protocolo UDP é apropriado para aplicações
tempo real, como telefonia e transferência de áudio e
vídeo sobre a Internet.

Devido a importância do protocolo, este laboratório tem o objetivo de
medir o tempo total e de comunicação de uma conexão UDP entre um
cliente e um servidor.

% -----------------------------------------------------------------------------%
\section{Servidor de agenda}
% -----------------------------------------------------------------------------%
O sistema implementado, uma agenda distribuída, se baseia numa comunicação
cliente-servidor. Nele o servidor possui todas as informações da
agenda que estão armazenadas em um banco de dados,
assim como as opções de interações com os dados que são apresentadas
aos clientes em formas de um menu.
O cliente só escolhe alguma opção de interação com os dados de
acordo com menu.


\subsection{Menu inicial}
No menu inicial pode-se:

\begin{itemize}
\item Logar
\item Criar novo usuário
\item Sair
\end{itemize}

\subsubsection{Login}
O servidor pede ao usuário o nome de usuário, caso o nome estiver no
banco de dados ele pede uma senha que é comparada ao valor do banco de
dados, se o usuário não existir é avisado sobre a inexistência, se a
senha não conferir é avisado que a senha não confere, caso contrário o
usuário consegue logar no sistema, e o servidor recupera sua agenda (cada
usuário possui sua agenda).


\subsubsection{Novo usuário}
O servidor pede um nome de usuário, o servidor verifica se o nome já
não existe, se não existir pede a senha e armazena o usuário no
sistema, assim como cria uma agenda vazia para o mesmo.

\subsection{Menu usuário}
Dentre as possibilidades de interações para um usuário logado tem-se:

\begin{itemize}
\item Inserção de um compromisso que possui um nome, dia, hora, e minuto. 
\item Remoção de um compromisso através de seu nome
\item Pesquisa de compromisso por dia
\item Pesquisa de compromisso por dia e hora
\item Ver todos os compromisso de mês de abril
\end{itemize}

\subsubsection{Inserção de compromisso}
O usuário deve fornecer o nome do compromisso, o dia, a hora e o
minutos em que ele ocorrerá.
Caso o compromisso seja possível de ser alocado o servidor avisa com
um ``OK'', se não for possível também é avisado de tal impossibilidade.
Um compromisso é inserido ordenado na agenda se não existir um
compromisso com mesmo horário.

\subsubsection{Remoção de compromisso}
O usuário deve fornecer o nome do compromisso que deve ser removido.
Caso o compromisso seja encontrado ele é removido, caso contrário é
dito que tal compromisso não existe.
Se existirem dois compromissos de mesmo nome, o primeiro é removido.
Logo é esperado que compromissos possuam nomes diferentes.


\subsubsection{Pesquisas}
O servidor faz um requerimento interativo, ou seja, se for selecionado
a pesquisa por dia e hora, o servidor pergunta primeiramente o dia e
depois a hora. Logo, é uma pesquisa em etapas no qual o servidor
interage com nosso usuário.

% -----------------------------------------------------------------------------%
\section{Ambiente de implementação}
% -----------------------------------------------------------------------------%
O sistema de agenda foi implementado e executado nos seguintes sistemas operacionais :
\begin{itemize}
\item FC14 - Fedora Laughlin Linux 2.6.35.11
\end{itemize}

O sistema de agenda foi implementado na linguagem C.
Para o armazenamento dos dados, utilizou-se arquivos. Cada usuário
possui um arquivo, a sua agenda, no qual armazena-se o nome do
compromisso, o dia, a hora e o minuto do mesmo.
O sistema lê esse arquivo quando o usuário loga e transfere-o à
memória principal, e a cada alteração na agenda o servidor atualiza as informações dos arquivos.

O servidor aceita diversas conexões de clientes, funcionando
perfeitamente para interações em diferentes agendas, pois cada
cliente possui além de um processo único, que foi criado em um fork,
possui um ponteiro para sua agenda. Assim, o servidor consegue
alterar todas as agendas independentemente.

 O nosso sistema, além disso,apresenta
transparência ao usuário. Os tipos de transparência a serem destacados
são:

\begin{description}
\item [Acesso:] Esconde as diferenças nas representações de dados e na invocação de funções ou métodos para facilitar a comunicação entre objetos da rede.
\item [Localização:] Esconde o local em que o objeto se encontra.
\item [Concorrência:] Esconde como as atividades são coordenadas entre os objetos para obter consistência em um nível mais alto.
\end{description}


Listaremos a seguir algumas funções implementadas de interação:
\begin{itemize}
\item  Funções de interação com o banco de dados são:
  \begin{lstlisting}
    /* Encontra usuario que ja esta cadastrado no servidor e verifica
    senha*/
    int findUser(char nome[], char pwd[]);
    
    /* Insere novo usuario (nome e senha) no banco de dados*/
    int newUser(char nome[], char senha[]);
    
    /*Carrega agenda de usuario*/
    int loadCal(User *user);
    
    /*Salva agenda*/
    int saveCal(User *user);
  \end{lstlisting}

\item Funções de interação com a agenda  são:

  \begin{lstlisting}
    /*Cria agenda para usuario*/
    User * agenda_init(char nome[]);

    /*Apaga agenda da memoria principal do servidor */
    void user_destroy(User *u);

    /*Insere compromisso na agenda*/
    int set_task(int dia,int hora, int min,char task[], User *u);

    /*Cria compromisso */
    Agenda * task_init(int dia,int hora, int min,char task[]);

    /*Retorna compromissos do mes de abril*/
    int verMes(int new_fd, User *u,struct sockaddr_storage their_addr);

    /*Retorna compromissos do mes de abril em determinado dia*/
     int verDia(int new_fd, User *u, int dia,struct sockaddr_storage their_addr);
    
    /*Retorna compromissos do mes de abril em determinado dia e
    determinada hora*/
    int verHora(int new_fd, User *u, int dia, int hora,struct sockaddr_storage their_addr);

    /*Remove compromisso da agenda pelo nome*/
    int delTask( User *u, char nome[]);

    /*Comapara data de compromissos*/
    int compData(Agenda *newTasks,Agenda *tasks);

  \end{lstlisting}

\item Funções de interação servidor-cliente criadas foram:
  \begin{lstlisting}

    /*Envia mensagem ao cliente*/
	void sendMsg(int new_fd, char str[],struct sockaddr_storage their_addr);
	
    /*Le mensagem do cliente*/
    int leOpcao(struct sockaddr_storage their_addr, int sockfd);
    
    /*Apresenta opcoes de login ou criacao novo usuario*/
    void menu(int new_fd, struct sockaddr_storage their_addr);
    
    /*Apresenta opcoes de interacao com agenda*/
    void menu2(int new_fd, struct sockaddr_storage their_addr, User *user);

    /*Envia mensagem para servidor*/
    void envia_pct( int sockfd, char s[], int size){

    \end{lstlisting}


  \end{itemize}


  \section{Tempos de comunicação e total}

Aplicamos o cálculo de tempo ao programa principal de
  forma a obtermos o tempo total,  tempo de comunicação e os tempos da
  execução de cada função.
  Para o tempo total, no cliente pega-se o tempo antes do primeiro send e após o último recv.
  Para o tempo de comunicação, pega-se o tempo total e subtrai-se o tempo de processamento do servidor,
  que é depois do primeiro recv e antes do último send.

  Para o tempo total das funções obteu-se o tempo de inserir um
  compromisso, remover o compromisso, ver a agenda do mês, ver a agenda
  de um dia, ver a agenda de uma hora. Os dados e os testes estão
  exemplificados nas tabelas \ref{op1}, \ref{op2}, \ref{op3},
  \ref{op4} e \ref{op5}.

  O resultado obtido para 100 valores foi:

  \begin{table}[h!]
    \begin{center}

      \subfloat[Tempo total]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 7.636 ms\\
		Min & 4.290 ms\\
		Media & 4.911 ms\\
		Desvio & 0.026 ms

        \end{tabular}
        \label{total}
      }
      \hspace{30mm}
      \subfloat[Tempo de comunicação]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 0.526 ms\\
          Min & 0.116 ms\\
          Média & 0.200 ms \\
          Desvio & 0.002 ms
        \end{tabular}
        \label{comu}
      }

    \end{center}
    \vspace{-5mm}
    \caption{Conexão e fechamento de conexão com servidor} \label{op}
  \end{table}


  \begin{table}[h!]

    \begin{center}

      \subfloat[Tempo total]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
		Max & 57.486 ms\\
		Min & 46.765 ms\\
		Media & 50.218 ms\\
		Desvio & 0.188 ms
        \end{tabular}
        \label{total1}
      }
      \hspace{30mm}      
     \subfloat[Tempo de comunicação]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
		Max & 1.021 ms\\
		Min & 0.119 ms\\
		Media & 0.215 ms\\
		Desvio & 0.010 ms
        \end{tabular}
        \label{comu1}
      }

    \end{center}
    \vspace{-5mm}
    \caption{Conexão, login na conta, inserção de compromisso e
      fechamento de conexão com servidor} \label{op1}
  \end{table}


  \begin{table}[h!]
    \begin{center}
      \subfloat[Tempo total]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 84.467 ms\\
		Min & 35.519 ms\\
		Media & 41.636 ms\\
		Desvio & 0.112 ms
        \end{tabular}
        \label{total2}
      }
      \hspace{30mm}
      \subfloat[Tempo de comunicação]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
		Max & 0.502 ms\\
		Min & 0.113 ms\\
		Media & 0.200 ms\\
		Desvio & 0.001 ms
        \end{tabular}
        \label{comu2}
      }
    \end{center}
    \vspace{-5mm}
    \caption{Conexão, login na conta, remoção de compromisso} \label{op2}
 \end{table}

  \begin{table}[h!]
    \begin{center}

      \subfloat[Tempo total]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 84.261 ms\\
		Min & 35.159 ms\\
		Media & 43.995 ms\\
		Desvio & 0.259 ms
        \end{tabular}
        \label{total3}
      }
      \hspace{30mm}
      \subfloat[Tempo de comunicação]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
		Max & 0.126 ms\\
		Min & 0.045 ms\\
		Media & 0.074 ms\\
		Desvio & 0.002 ms
        \end{tabular}
        \label{comu3}
      }

    \end{center}
    \vspace{-5mm}
    \caption{Conexão, login na conta, ver compromissos de determinado
      dia e hora e fechamento de conexão com servidor} \label{op3}
  \end{table}

  \begin{table}[h!]
    \begin{center}

      \subfloat[Tempo de total]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
		Max & 38.274 ms\\
		Min & 33.887 ms\\
		Media & 35.707 ms\\
		Desvio & 0.182 ms
        \end{tabular}
        \label{total4}
      }
      \hspace{30mm}
      \subfloat[Tempo de comunicação]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 3.154  ms\\
          Min & 0.110 ms\\
          Média & 0.251 ms \\
          Desvio & 0.005 ms
        \end{tabular}
        \label{comu4}
      }

    \end{center}
    \vspace{-5mm}
    \caption{Conexão, login na conta, ver todos os compromisso do dia
      e fechamento de conexão com servidor} \label{op4}
  \end{table}


  \begin{table}[h!]

    \begin{center}

      \subfloat[Tempo total]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 50.721 ms\\
		Min & 31.098 ms\\
		Media & 35.774 ms\\
		Desvio & 0.162 ms
        \end{tabular}
        \label{total5}
      }
      \hspace{30mm}      
     \subfloat[Tempo de comunicação]{
        \begin{tabular}{lr}
          \multicolumn{1}{c}{Valor} & \multicolumn{1}{c}{Tempo}\\
          \hline
          Max & 3.834 ms\\
          Min & 0.117 ms\\
          Média & 0.241 ms \\
          Desvio & 0.001 ms
        \end{tabular}
        \label{comu5}
      }

    \end{center}
    \vspace{-5mm}
    \caption{Conexão, login na conta, ver todos os compromissos do mês
      e fechamento de conexão com servidor} \label{op5}
  \end{table}

\clearpage

  \subsection{Comparação de tecnologias}
Como uma das características do TCP é a transferência garantida ,não foi necessário uma análise de erros na entrega
dos pacotes. No entanto, essa análise foi feita ao utilizar o protocolo UDP, através de um código de verificação.
Portanto o protocolo TCP possibilita uma redução no tamanho do código.

Para que o nosso sistema distribuído fosse transparente ao usuário, diversas manipulações de dados foram realizadas
no servidor, assim, algumas transparências, como localidade, acesso e concorrência, foram possíveis.

Como o TCP é orientado à conexão, é criado um socket para cada cliente se comunicar com o servidor e ele é livre
de erros. Utilizando a função fork temos um processo que fica à escuta de novos pedidos de conexão e outro processo
trata da conexão com o cliente. Já o UDP não é orientado a conexão, não é confiável e o envio de pacotes pode chegar em
diferentes ordens.

Devido as diferentes características do UDP como, por exemplo, o não há tratamento de erros e não ser orientado a
conexão, é esperado que ele tenha um tempo inferior ao TCP. Mas, deve-se lembrar que os erros deverão ser verificados
pelo programa principal, assim como o ordenamento das mensagens.
O tempo de processamento (manipulação da agenda) teoricamente não deve alterar pela utilização dos diferentes
protocolos.
Portanto, é esperado o tempo total será alterado devido ao tempo de comunicação.

Após a utilização de ambas tecnologias, colocamos os tempo médios totais para todas as funções, apresentadas nas tabelas \ref{comptot} e \ref{compcom}.
\begin{table}[h!]
  \begin{center}
    \begin{tabular}{ccc}
      
      Função& TCP&  UDP \\
      \hline
      F0 & 3.865 ms & 4.911 ms\\
      F1 & 36.782 & 50.218 ms\\
      F2 & 35.707 ms & 41.636 ms\\
      F3 & 35.774 ms & 43.995 ms\\
      F4 & 38.612 ms & 35.707 ms\\
      F5 & 32.334 ms & 35.774 ms
    \end{tabular}
  \end{center}
      \vspace{-5mm}
    \caption{Comparação de tempos totais} \label{comptot}
\end{table}

\begin{table}[h!]
  \begin{center}
  
    \begin{tabular}{ccc}
      
      Função& TCP&  UDP \\
      \hline
      F0 & 0.705 ms & 0.200 ms\\
      F1 & 0.725 & 0.215 ms\\
      F2 & 0.705 ms & 0.200 ms\\
      F3 & 0.715 ms & 0.074 ms\\
      F4 & 0.727 ms & 0.251 ms\\
      F5 & 0.716 ms & 0.241 ms
    \end{tabular}
  \end{center}
      \vspace{-5mm}
    \caption{Comparação de tempos de comunicação} \label{compcom}
\end{table}

Para a maioria das funções, baseado no tempo total, o protocolo TCP
foi mais rápido que o UDP; houve um aumento de 10\% a 40\% nos tempos
das funções . Mas, se for analisado o tempo de
comunicação, o UDP é, em média, 0.5ms mais rápido, correspondendo à uma diminuição
de aproximadamente 70\% do tempo.


\section{Conclusão}
Segundo nossas medições, os tempos de processamento são significativamente (cerca de duas ordens de grandeza)
maiores que os tempos de conexão, ou seja, há uma transparência de localidade para o cliente, já que o tempo de comunicação é tão pequeno que a agenda será aparentemente local para o cliente.

Comparando as duas tecnologias (TCP e UDP), a utilização do UDP proporcionou  tempo total maior que o TCP. 
Por outro lado, o tempo de comunicação, utilizando o UDP, foi inferior, conforme
esperado.

Assim, para aplicações em tempo real, o UDP acaba levando vantagem, já que
não há perda de tempo com a comunicação. Por outro lado, o gasto
de tempo com a verificação de erros é maior, que é dispensável, dependendo
da aplicação. Em uma distribuição de video em \textit{streaming}, por exemplo,
 erros e perdas de dados são ignoradas para não se abrir mão da
 reprodução de video em tempo real.

% ******************************************************
% REFERENCIAS BIBLIOGRÁFICAS
% ******************************************************
% \section{Referências}
\bibliographystyle{plain}
\begin{small}
  \bibliography{referencias}
\end{small}
\newpage
\section{Anexo}

\lstset{
  basicstyle=\tiny\ttfamily, % Standardschrift
  numbers=left,               % Ort der Zeilennummern
  numberstyle=\tiny,          % Stil der Zeilennummern
  numbersep=5pt,              % Abstand der Nummern zum Text
  tabsize=2,                  % Groesse von Tabs
  extendedchars=true,         %
  breaklines=true,            % Zeilen werden Umgebrochen
  classoffset=0,
  keywordstyle=\color{blue},
  classoffset=1,
  morekeywords={factor},keywordstyle=\color{red},
  classoffset=0,
  stringstyle=\color{green}\ttfamily, % Farbe der String
  showspaces=false,           % Leerzeichen anzeigen ?
  showtabs=false,             % Tabs anzeigen ?
  xleftmargin=17pt,
  framexleftmargin=17pt,
  framexrightmargin=5pt,
  framexbottommargin=4pt,
  showstringspaces=false      % Leerzeichen in Strings anzeigen ?        
}
\lstloadlanguages{C
}

\begin{multicols}{2}
\lstinputlisting[language=c,caption={Agenda }]{code/rel/agenda.c}
\lstinputlisting[language=c,caption={banco de dados}]{code/rel/bd.c}
\lstinputlisting[language=c,caption={Servidor }]{code/rel/server.c}
\lstinputlisting[language=c,caption={Cliente  }]{code/rel/client.c}
\lstinputlisting[language=c,caption={Cabeçalhos Banco de dados}]{code/rel/bd.h}
\lstinputlisting[language=c,caption={Cabeçalhos Agenda}]{code/rel/agenda.h}
\lstinputlisting[language=c,caption={Makefile}]{code/rel/Makefile}
\end{multicols}
\end{document}
